1. Field of the Invention
The present invention generally relates to software development. More particularly, the invention is directed to techniques for debugging the source code of multithreaded computer programs.
2. Description of the Related Art
A programmer usually develops a software program using a text editor to create source code files. From these source code files, an executable program is generated by translating the source code files into an executable program. The process of generating the executable program from the source code usually involves the use of several software programs. For example, a compiler program may be used to generate a set of object code modules from the source code file, and a linker may be used to link the modules together to form the executable program.
It is not uncommon for the source code files of a computer program to include thousands, if not millions, of lines of source code, often spread across many files. Because of this complexity, software programs often contain errors that manifest themselves during program execution (commonly referred to as bugs). Accordingly, a debugging tool has become an essential tool of software development. Typically, a debugger program allows a developer to monitor the execution of a computer program. Doing so assists a programmer in finding and correcting errors. A typical debugging system includes a combination of computer hardware and debugger software that executes the program being debugged in a controlled manner. For example, a user interface provided for the debugger typically allows a user to set breakpoints at lines of code. During program execution, when the executing program encounters a breakpoint, the program ceases executing and turns control over to the debugger, allowing the developer to examine the state of the program at the breakpoint.
Additionally, debuggers often provide a variety of other debugging commands that allow a user to control the execution of a program. For example, one common debugger command allows a user to “step” through lines of source code, executing the program line-by-line. When a user issues a step command, the program executes the machine instructions corresponding to the line of source code based on the current execution point of the program, and advances the execution point to the next line of source code. Step commands typically take one of two forms: step into and step over. A step over command causes the program to execute the current line of code and set the execution point of the program to the next line of source code. If the line of code contains a function call (i.e., it invokes a routine or method defined by the program), then the program executes all of the instructions specified by the function. In contrast, the step into command will set the execution point of the program to the first line of code for the function, allowing a programmer to step through each of the instructions specified by the function.
Multithreading is a programming model that allows multiple threads to exist within the context of a single process, sharing the process' resources but able to execute independently. The threaded programming model provides developers with a useful abstraction of concurrent execution.
This advantage allows multithreaded programs to operate faster on computer systems that have multiple central processing units (CPUs), multiple cores, or across a cluster of machines. This is because the threads of the program naturally lend themselves to truly concurrent execution. In such a case, the programmer needs to be careful to avoid race conditions, and other non-intuitive behaviors. In order for data to be manipulated correctly, threads often need to rendezvous in time in order to process the data in the correct order. Threads may also require atomic operations (often implemented using locking mechanisms such as semaphores, mutexes, or the like) to prevent common data from being simultaneously modified, or read while in the process of being modified.